package com.neusoft.neuiotms.dcvm.task.cmdbSyn.service.impl;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.neusoft.bizcore.web.utils.JsonUtils;
import com.neusoft.neuiotms.dcvm.bean.AttrBean;
import com.neusoft.neuiotms.dcvm.service.AssetService;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.constants.CmdbSynConstants;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.model.RackUnitUsage;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.model.enums.LeaseStatus;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.model.enums.RackTypeStatus;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.respository.RackUnitUsageRepository;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.service.CmdbRackSynService;
import com.neusoft.neuiotms.dcvm.task.cmdbSyn.service.ItSynApiService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class CmdbRackSynServiceImpl implements CmdbRackSynService {
    @Autowired
    private ItSynApiService itSynService;
    @Autowired
    private AssetService cmdbMicroService;
    @Autowired
    private RackUnitUsageRepository rackUnitUsageRepository;

    @Value(value = "${readlocal: false}")
    private boolean readlocal;

    @Override
    @Transactional
    //@Scheduled(initialDelay = 10000, fixedDelay = 365 * 10 * 24 * 3600000)
    public void doUpdate() {
        try {
            // 查询cmdb所有机柜
            //		final JSONObject cmdbRackListJo = cmdbMicroService.getAllCiBySchema2("5f3cfc291a0fcdfd2aa9a182");
            //		final JSONArray cmdbRackArray = cmdbRackListJo.getJSONArray("data");
            //		final Map<String, String> rackRelMap = cmdbRackArray.toJavaList(JSONObject.class).stream().collect(Collectors.toMap(x->x.getString("name"), y->y.getString("code")));
            // 获取机柜接口数据
            JSONObject rackListData = null;
            if (this.readlocal) {
                rackListData = this.itSynService.getMockRackListData();
            } else {
                rackListData = this.itSynService.getRackListData();
            }
            //String rackStr = "{\"rspCode\":\"0\",\"rspDesc\":\"成功\",\"rackList\":[{\"dataCenterCode\":\"中国移动（云南昆明）数据中心\",\"dataCenterName\":\"DC-871-04\",\"bulidingCode\":\"BD-871-04-B1\",\"buildingName\":\"B01生产楼\",\"roomCode\":\"RM-871-04-01-001\",\"roomName\":\"呈贡县中国移动（云南昆明）数据中心B01二楼201数据机房\",\"rackCode\":\"RACK-871-18-03-301-A02\",\"rackName\":\"呈贡县中国移动（云南昆明）数据中心B01二楼201数据机房/IDC01-201-A03\",\"rackType\":\"政企业务\",\"leaseStatus\":\"占用\",\"totalUnit\":49},{\"dataCenterCode\":\"中国移动（云南昆明）数据中心\",\"dataCenterName\":\"DC-871-04\",\"bulidingCode\":\"BD-871-04-B1\",\"buildingName\":\"B01生产楼\",\"roomCode\":\"RM-871-04-01-005\",\"roomName\":\"呈贡县中国移动（云南昆明）数据中心B01四楼401数据机房\",\"rackCode\":\"RACK-871-04-B1-401-I00\",\"rackName\":\"B01生产楼401-I00\",\"rackType\":\"政企业务\",\"leaseStatus\":\"占用\",\"totalUnit\":49}]}";
            //JSONObject rackListData = JSON.parseObject(rackStr);
            final JSONArray rackArray = rackListData.getJSONArray("rackList");
            if (!rackArray.isEmpty()) {
                rackArray.forEach(rack -> {
                    final JSONObject rackjo = (JSONObject) rack;
                    final String rackCode = rackjo.getString("rackCode");
                    final String rackName = rackjo.getString("rackName");
                    List<AttrBean> cmdbUpdateAttr = null;
                    try {
                        // 从CMDB查找机柜预置信息
                        final JSONObject result = this.cmdbMicroService.globalSearch(rackCode);

                        if ((null != result) && !result.getJSONArray("data").isEmpty()) {
                            final JSONObject ciJsonObj = result.getJSONArray("data").getJSONObject(0);
                            final String cmdbCode = ciJsonObj.getJSONArray("data")
                                    .getJSONObject(0).getString("code");

                            // 更新
                            cmdbUpdateAttr = this.getCmdbUpdateAttr(rackjo);
                            // 计算uInfo--start
                            //                            String uInfoStr = this.initUInfoField(rackjo.getIntValue("totalUnit"));
                            //                            uInfoStr = this.setUInfoField(uInfoStr, rackjo.containsKey("rackUnitList")
                            //                                    ? rackjo.getJSONArray("rackUnitList") : null);
                            //                            final AttrBean uInfoAttrBean = new AttrBean();
                            //                            uInfoAttrBean.setKey("uInfo");
                            //                            uInfoAttrBean.setValue(uInfoStr);
                            //                            cmdbUpdateAttr.add(uInfoAttrBean);
                            // 计算uInfo--end

                            CmdbRackSynServiceImpl.log.info("开始更新机柜{},属性信息:{}", cmdbCode,
                                    JsonUtils.pojoToJson(cmdbUpdateAttr));
                            this.cmdbMicroService.updateInstancesAttrs(cmdbCode, cmdbUpdateAttr);
                            CmdbRackSynServiceImpl.log.info("结束更新机柜{}", cmdbCode);

                            if (rackjo.containsKey("rackUnitList")) {
                                final JSONArray rackUnitList = rackjo.getJSONArray("rackUnitList");

                                final List<RackUnitUsage> usageList = Lists.newArrayList();
                                for (int i = 0; i < rackUnitList.size(); i++) {
                                    final RackUnitUsage data = new RackUnitUsage();
                                    data.setRackCode(rackCode);
                                    data.setRackName(rackName);
                                    final JSONObject jo = (JSONObject) rackUnitList.get(i);
                                    final Set<String> itemKeySet = jo.keySet();
                                    for (final String key : itemKeySet) {
                                        final Object synData = jo.get(key);
                                        try {
                                            Field field = null;
                                            field = RackUnitUsage.class.getDeclaredField(key);
                                            final String methodStr =
                                                    "set" + key.toUpperCase().substring(0, 1) + key.substring(1);
                                            Method method = null;
                                            method = RackUnitUsage.class.getMethod(methodStr,
                                                    new Class[] {field.getType() });

                                            method.invoke(data, synData);

                                            usageList.add(data);
                                        } catch (final Exception e) {
                                            CmdbRackSynServiceImpl.log.error("", e);
                                        }
                                    }
                                }

                                this.rackUnitUsageRepository.deleteByRackCode(rackCode);
                                this.rackUnitUsageRepository.saveAll(usageList);
                            }

                        }
                    } catch (final Exception e) {
                        CmdbRackSynServiceImpl.log.error("更新机柜编码{},attr:{},发生异常:{}", rackCode,
                                JsonUtils.pojoToJson(cmdbUpdateAttr),
                                e.getMessage());
                        CmdbRackSynServiceImpl.log.error("", e);
                    }
                });
            }
        } catch (final Exception e) {
            CmdbRackSynServiceImpl.log.error("更新机柜字段发生异常:{}", e.getMessage());
        }
    }

    public List<AttrBean> getCmdbUpdateAttr(final JSONObject rack) {
        final List<AttrBean> listAttr = new ArrayList<>();
        final Map<String, String> attrs = new HashMap<>();
        attrs.put(CmdbSynConstants.ASSET_DEL_ATTR_CODE, "0");
        attrs.put(CmdbSynConstants.SYN_TIME_ATTR_CODE, String.valueOf(new Date().getTime()));
        attrs.put("rackType", this.getRackTypeValue(rack.getString("rackType")));
        attrs.put("leaseStatus", this.getLeaseStatusValue(rack.getString("leaseStatus")));

        final Iterator<Entry<String, String>> it = attrs.entrySet().iterator();
        while (it.hasNext()) {
            final AttrBean item = new AttrBean();
            final Entry<String, String> next = it.next();
            item.setKey(next.getKey());
            item.setValue(next.getValue());
            listAttr.add(item);
        }
        return listAttr;
    }

    private String getRackTypeValue(final String name) {
        final List<RackTypeStatus> list = Arrays.stream(RackTypeStatus.values()).collect(Collectors.toList());
        final List<RackTypeStatus> matchList = list.stream().filter(item -> item.getDesc().equals(name))
                .collect(Collectors.toList());
        return matchList.isEmpty() ? RackTypeStatus.yl.getValue() : matchList.get(0).getValue();
    }

    private String getLeaseStatusValue(final String name) {
        final List<LeaseStatus> list = Arrays.stream(LeaseStatus.values()).collect(Collectors.toList());
        final List<LeaseStatus> matchList = list.stream().filter(item -> item.getDesc().equals(name))
                .collect(Collectors.toList());
        return matchList.isEmpty() ? LeaseStatus.kx.getValue() : matchList.get(0).getValue();
    }

    /**
     * 根据totalUnit重新初始化字符串为totalUnit个0
     *
     * @param totalUnit
     * @return
     */
    @SuppressWarnings("unused")
    private String initUInfoField(int totalUnit) {
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < totalUnit; i++) {
            sb.append("0");
        }
        return sb.toString();
    }

    /**
     * 根据startUnit和endUnit更新uInfo状态
     *
     * @param totalUnit
     * @return
     */
    @SuppressWarnings("unused")
    private String setUInfoField(String initStr, JSONArray rackUnitList) {
        if (null != rackUnitList) {
            for (int i = 0; i < rackUnitList.size(); i++) {
                final JSONObject jo = (JSONObject) rackUnitList.get(i);
                final int startUnit = jo.getIntValue("startUnit");
                final int endUnit = jo.getIntValue("endUnit");

                final char[] arr = initStr.toCharArray();

                for (int j = startUnit - 1; j < endUnit; j++) {
                    if (j < arr.length) {
                        arr[j] = '1';
                    }
                }

                initStr = String.valueOf(arr);
            }
        }

        return initStr;
    }

}
